package com.jplus.framework.util;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.math.BigDecimal;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 类操作工具类
 *
 * @author huangyong
 * @author Yuanqy
 */
public class ClassUtil {

	private static final Logger logger = LoggerFactory.getLogger(ClassUtil.class);

	/**
	 * 获取类加载器
	 */
	public static ClassLoader getClassLoader() {
		return Thread.currentThread().getContextClassLoader();
	}

	/**
	 * 获取类路径
	 */
	public static String getClassPath() {
		String classpath = "";
		URL resource = getClassLoader().getResource("");
		if (resource != null) {
			classpath = resource.getPath();
		}
		return classpath;
	}

	/**
	 * 加载类（将自动初始化）
	 */
	public static Class<?> loadClass(String className) {
		return loadClass(className, true);
	}

	/**
	 * 加载类
	 */
	public static Class<?> loadClass(String className, boolean isInitialized) {
		if(FormatUtil.isEmpty(className))
			return null;
		Class<?> cls;
		try {
			if (isInitialized)
				cls = Class.forName(className, isInitialized, getClassLoader());
			else
				cls = getClassLoader().loadClass(className);
		} catch (ClassNotFoundException e) {
			logger.error("Load class is error:"+className, e);
			throw new RuntimeException(e);
		}
		return cls;
	}

	/**
	 * 是否为 int 类型（包括 Integer 类型）
	 */
	public static boolean isInt(Class<?> type) {
		return type.equals(int.class) || type.equals(Integer.class);
	}

	/**
	 * 是否为 long 类型（包括 Long 类型）
	 */
	public static boolean isLong(Class<?> type) {
		return type.equals(long.class) || type.equals(Long.class);
	}

	/**
	 * 是否为 double 类型（包括 Double 类型）
	 */
	public static boolean isDouble(Class<?> type) {
		return type.equals(double.class) || type.equals(Double.class);
	}

	/**
	 * 是否为 BigDecimal 类型
	 */
	public static boolean isDecimal(Class<?> type) {
		return type.equals(BigDecimal.class);
	}

	/**
	 * 是否为 String 类型
	 */
	public static boolean isString(Class<?> type) {
		return type.equals(String.class);
	}

	// ==============================================

	@SuppressWarnings("serial")
	private static Set<Class<?>> ignoreAnno = new HashSet<Class<?>>() {
		{
			this.add(Documented.class);
			this.add(Inherited.class);
			this.add(Retention.class);
			this.add(Target.class);
		}
	};

	public static boolean ckPresentAnno(Class<?> cls, Class<? extends Annotation> eqCls, boolean isRecursive) {
		if (cls.isAnnotationPresent(eqCls))
			return true;
		else {
			if (!isRecursive)// 不递归
				return false;
			Annotation[] ans = cls.getAnnotations();
			boolean bo = false;
			for (Annotation an : ans) {
				if (!ignoreAnno.contains(an.annotationType())) {
					if (ckPresentAnno(an.annotationType(), eqCls, isRecursive)) {
						bo = true;
						break;
					}
				}
			}
			return bo;
		}
	}
}
